﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ApiBetaSeries.Factories;
using System.Security.Cryptography;
using System.Xml;

namespace ApiBetaSeries.Services
{
    public class UserServices : ApiBetaSeries.Services.IUserServices
    {
        #region singleton
        private static UserServices m_episodeServices = null;
        private UserServices() { }
        public static UserServices GetInstance()
        {
            if (m_episodeServices == null)
            {
                m_episodeServices = new UserServices();
            }
            return m_episodeServices;
        }
        #endregion
        /// <summary>
        /// Add a show to the member
        /// </summary>
        /// <param name="token">token of the member</param>
        /// <param name="urlSerie">the show</param>
        [ApiBetaSeries.Version.ApiMethod(false, "shows/add")]
        public void AddShowInUser(string token, IShow show)
        {
            AddShowInUser(token, show.Url);
        }
        /// <summary>
        /// Add a show to the member
        /// </summary>
        /// <param name="token">token of the member</param>
        /// <param name="urlSerie">url of the show</param>
        [ApiBetaSeries.Version.ApiMethod(false, "shows/add")]
        public void AddShowInUser(string token, string urlSerie)
        {
            IUser user = UserFactory.CreateUser();
            user.Token = token;
            user.AddShow(urlSerie);
        }

        /// <summary>
        /// remove a show from a member
        /// </summary>
        /// <param name="token">token of the member</param>
        /// <param name="urlSerie">the show</param>
        [ApiBetaSeries.Version.ApiMethod(false, "shows/remove")]
        public void DelShowInUser(string token, IShow show)
        {
            DelShowInUser(token, show.Url);
        }
        /// <summary>
        /// remove a show from a member
        /// </summary>
        /// <param name="token">token of the member</param>
        /// <param name="urlSerie">url of the show</param>
        [ApiBetaSeries.Version.ApiMethod(false, "shows/remove")]
        public void DelShowInUser(string token, string urlSerie)
        {
            IUser user = UserFactory.CreateUser();
            user.Token = token;
            user.DelShow(urlSerie);
        }


        /// <summary>
        /// Destroy a token
        /// Disconnect a member
        /// </summary>
        /// <param name="token">token to destroy</param>
        [ApiBetaSeries.Version.ApiMethod(false, "members/destroy")]
        public void DestroyToken(string token)
        {
            IUser user = UserFactory.CreateUser();
            user.Token = token;
            user.Destroy();
        }

        /// <summary>
        /// allow to know if a token is still active
        /// </summary>
        /// <param name="token">token to test</param>
        /// <returns>if the token is active</returns>
        [ApiBetaSeries.Version.ApiMethod(false, "members/is_active")]
        public bool IsActiveToken(string token)
        {
            IUser user = UserFactory.CreateUser();
            user.Token = token;
            return user.IsActive();
        }


        /// <summary>
        /// Auth an user by login and password
        /// </summary>
        /// <param name="username">login to log in</param>
        /// <param name="password">password to log in</param>
        /// <returns>the token</returns>
        [ApiBetaSeries.Version.ApiMethod(true, "members/auth")]
        public string Auth(string username, string password)
        {
            MD5 md5 = MD5.Create();
            byte[] data = md5.ComputeHash(Encoding.Default.GetBytes(password));
            StringBuilder sBuilder = new StringBuilder();
            for (int i = 0; i < data.Length; ++i)
            {
                sBuilder.Append(data[i].ToString("x2"));
            }

            string param = string.Format("&login={0}&password={1}", username, sBuilder.ToString());
            XmlDocument doc = Utils.UtilsXML.GetUrl("/members/auth.xml", param);
            XmlElement s = doc["root"]["member"]["token"];

            if (s == null)
            {
                throw new BetaSeriesException(1003, "Invalid action.");
            }

            return s.FirstChild.Value;

        }

        /// <summary>
        /// Auth an user by login and password
        /// </summary>
        /// <param name="username">login to log in</param>
        /// <param name="password">password to log in</param>
        /// <returns>an usern</returns>
        [ApiBetaSeries.Version.ApiMethod(false, "members/auth", "members/infos")]
        public IUser AuthUser(string username, string password)
        {
            IUser user = UserFactory.CreateUser();
            user.Token = Auth(username, password);
            user.GetInfos();
            return user;
        }

        /// <summary>
        /// Get all the info of an identified member
        /// </summary>
        /// <param name="token">token of the member</param>
        /// <returns>The user information</returns>
        [ApiBetaSeries.Version.ApiMethod(false, "members/infos")]
        public IUser GetInfos(string token)
        {
            IUser user = UserFactory.CreateUser();
            user.Token = token;
            user.GetInfos();
            return user;
        }

        /// <summary>
        /// get infos of a member
        /// </summary>
        /// <param name="username">username of the member</param>
        /// <returns>info of the member</returns>
        [ApiBetaSeries.Version.ApiMethod(false, "members/infos")]
        public IUser GetInfosOfMember(string username)
        {
            IUser user = UserFactory.CreateUser();
            user.Token = null;
            return user.GetInfosOfMember(username);
        }

        /// <summary>
        /// Get the username of all the friend of the member
        /// </summary>
        /// <param name="token">token of an identified member</param>
        /// <returns></returns>
        [ApiBetaSeries.Version.ApiMethod(false, "members/friends")]
        public System.Collections.Generic.List<string> GetFriends(string token)
        {
            IUser user = UserFactory.CreateUser();
            user.Token = token;
            return user.GetFriends();
        }

        /// <summary>
        /// Get the username of all the friend of the member
        /// </summary>
        /// <param name="username">username of the member</param>
        /// <returns></returns>
        [ApiBetaSeries.Version.ApiMethod(false, "members/friends")]
        public System.Collections.Generic.List<string> GetFriendsOfMember(string username)
        {
            IUser user = UserFactory.CreateUser();
            user.Login = username;
            return user.GetFriends();
        }
    }
}
